package com.ys.chatserver.http.logic;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.eva.framework.Processor;
import com.eva.framework.dbpool.DBDepend;
import com.eva.framework.dto.SysActionConst;
import com.eva.framework.utils.EndsExceptionFactory;
import com.google.gson.Gson;
import com.ys.chatserver.common.dto.cnst.RetResult;
import com.ys.chatserver.common.dto.cnst.ShortUuidUtil;
import com.ys.chatserver.http.logic.dto.*;
import com.ys.chatserver.tool.EmptyUtils;
import com.ys.chatserver.http.logic.dto.CaseUserType;
import com.ys.chatserver.http.logic.dto.StructureInfoVO;

import java.util.*;

public class CaseInfoProccessor implements SysActionConst, Processor {

    private final Gson gson = new Gson();

    @Override
    public Object process(int job_dispatch_id, int action_id, Object newData, Object oldData, User user) throws Exception {
        Object ret = null;
        String newDataJSON = (String) newData;

        if (job_dispatch_id == JobDispatchConst.LOGIC_GROUP_CASE) {
            ret = maintainMgrCaseJobDispatcher(action_id, newDataJSON, oldData, user);
        } else {
            throw EndsExceptionFactory.INVALID_JOB_DISPATCHER_ID(job_dispatch_id);
        }
        return ret;
    }

    private Object maintainMgrCaseJobDispatcher(int actionId, String newDataJSON, Object oldData, User user) throws Exception {

        switch (actionId) {
            case ACTION_ADD_CASE: {//创建案件
                JSONObject jsonObj = JSON.parseObject(newDataJSON);
                //创建者名称
                String creatorName = jsonObj.getString("creatorName");
                //创建案件名称
                String structureName = jsonObj.getString("structureName");

                String structureDesc = jsonObj.getString("structureDesc");

                if (EmptyUtils.isEmpty(structureName) || EmptyUtils.isEmpty(creatorName)) {
                    return gson.toJson(RetResult.failResult("参数错误!"));
                }
                if (Boolean.TRUE.equals(isAdmin(user.getUserId()))) {
                    return gson.toJson(RetResult.failResult("权限拒绝,请使用普通账户创建"));
                }
                List<StructureInfoVO> vos = new ArrayList<>();
                String structuresNo = ShortUuidUtil.getShortUuid();
                StructureInfoVO vo = new StructureInfoVO();
                vo.setStructureNo(structuresNo);
                vo.setStructureName(structureName);
                vo.setStructureType(1);
                vo.setCreatorName(creatorName);
                vo.setCreatorId(user.getUserId());
                vo.setStructureLevel(structuresNo);
                vo.setParentNo(structuresNo);
                vo.setRootNo(structuresNo);
                vo.setStructureDesc(structureDesc);
                vos.add(vo);
                return addStructures(vos);
            }
            case ACTION_NODE_CASE: {//创建子节点
                JSONObject jsonObj = JSON.parseObject(newDataJSON);
                //创建者名称
                String creatorName = jsonObj.getString("creatorName");
                //创建案件名称
                String structureName = jsonObj.getString("structureName");
                //父级编码
                String parentNo = jsonObj.getString("parentNo");
                //节点类型
                String caseType = jsonObj.getString("caseType");
                if (EmptyUtils.isEmpty(parentNo) || EmptyUtils.isEmpty(creatorName) || EmptyUtils.isEmpty(parentNo) || EmptyUtils.isEmpty(caseType)) {
                    return gson.toJson(RetResult.failResult("参数错误!"));
                }
                Vector<Vector<?>> vector = queryLevelByNo(parentNo);
                if (vector.isEmpty()) {
                    return gson.toJson(RetResult.failResult("父级编码不存在！"));
                }
                if (Boolean.TRUE.equals(finishStructure(parentNo))) {
                    return gson.toJson(RetResult.failResult("案件已完结，禁止编辑!"));
                }
                if (Boolean.TRUE.equals(exitStructureName(parentNo, structureName))) {
                    return gson.toJson(RetResult.failResult("该案件下名称['" + structureName + "']已存在,请勿重复创建!"));
                }
                if (Boolean.FALSE.equals(isObserver(parentNo, user.getUserId()))) {
                    return gson.toJson(RetResult.failResult("暂无权限！"));
                }
                String structureLevel = vector.get(0).get(0).toString();
                String rootNo = vector.get(0).get(1).toString();
                List<StructureInfoVO> vos = new ArrayList<>();
                String structuresNo = ShortUuidUtil.getShortUuid();
                StructureInfoVO vo = new StructureInfoVO();
                vo.setStructureNo(structuresNo);
                vo.setStructureName(structureName);
                vo.setCaseType(caseType);
                vo.setStructureType(1);
                vo.setCreatorName(creatorName);
                vo.setCreatorId(user.getUserId());
                vo.setStructureLevel(structureLevel + ":" + structuresNo);
                vo.setParentNo(parentNo);
                vo.setRootNo(rootNo);
                vos.add(vo);
                return addStructures(vos);
            }
            case ACTION_UPDATE_CASE: { //修改AJ信息
                JSONObject jsonObj = JSON.parseObject(newDataJSON);
                String structureNo = jsonObj.getString("structureNo");
                String structureName = jsonObj.getString("structureName");
                String structureDesc = jsonObj.getString("structureDesc");
                Integer gb28181Export = jsonObj.getInteger("gb28181Export");
                if (EmptyUtils.isEmpty(structureNo)) {
                    return gson.toJson(RetResult.failResult("参数错误!"));
                }
                if (Boolean.TRUE.equals(finishStructure(structureNo))) {
                    return gson.toJson(RetResult.failResult("案件已完结，禁止编辑!"));
                }
                if (Boolean.FALSE.equals(isObserver(structureNo, user.getUserId()))) {
                    return gson.toJson(RetResult.failResult("暂无权限！"));
                }
                return updateStructuresByNo(structureNo, structureName, structureDesc, gb28181Export);
            }
            case ACTION_DELETE_CASE: { //删除AJ
                JSONObject jsonObj = JSON.parseObject(newDataJSON);
                String structureNo = jsonObj.getString("structureNo");
                if (EmptyUtils.isEmpty(structureNo)) {
                    gson.toJson(RetResult.failResult("参数错误|"));
                }
                if (Boolean.TRUE.equals(finishStructure(structureNo))) {
                    return gson.toJson(RetResult.failResult("案件已完结，禁止编辑!"));
                }
                if (Boolean.FALSE.equals(isObserver(structureNo, user.getUserId()))) {
                    return gson.toJson(RetResult.failResult("暂无权限！"));
                }
                return deleteStructuresByNo(structureNo);
            }
            case ACTION_QUERY_CASE: { //查询AJ列表
                String creatorId = user.getUserId();
                return queryByNoAndId(creatorId);
            }
            case ACTION_FINISH_CASE: {//AJ完结
                JSONObject jsonObj = JSON.parseObject(newDataJSON);
                String structureNo = jsonObj.getString("structureNo");
                if (EmptyUtils.isEmpty(structureNo)) {
                    gson.toJson(RetResult.failResult("参数错误|"));
                }
                if (Boolean.FALSE.equals(isCreator(structureNo, user.getUserId()))) {
                    return gson.toJson(RetResult.failResult("权限拒绝,仅创建者可操作！"));
                }
                return finishStructureByNo(structureNo);
            }
            case ACTION_EXPORT_GB28181: {//gb28181导出
                JSONObject jsonObj = JSON.parseObject(newDataJSON);
                String structureNo = jsonObj.getString("structureNo");
                if (EmptyUtils.isEmpty(structureNo)) {
                    gson.toJson(RetResult.failResult("参数错误|"));
                }
                if (Boolean.FALSE.equals(isCreator(structureNo, user.getUserId()))) {
                    return gson.toJson(RetResult.failResult("权限拒绝,仅创建者可操作！"));
                }
                if (Boolean.TRUE.equals(finishStructure(structureNo))) {
                    return gson.toJson(RetResult.failResult("案件已完结，禁止编辑!"));
                }
                if (Boolean.FALSE.equals(exoprtAuth(structureNo))) {
                    return gson.toJson(RetResult.failResult("此案件不支持导出功能"));
                }
                // TODO: 2023/8/24 存redis通知导出案件下设备文件
                notifyGb28181Export(structureNo);
                return gson.toJson(RetResult.successResult("操作成功！"));
            }
            default:
                throw EndsExceptionFactory.INVALID_ACTION_ID(actionId);
        }
    }

    private String queryByNoAndId(String creatorId) throws Exception {
        String sql = "select structure_no,structure_name,structure_level,creator_id,creator_name,parent_no,is_finish,create_time,finish_time,structure_type,case_type,structure_desc,gb28181_export" +
                " from structure_info WHERE creator_id in (select user_id from structure_user_info where " +
                "structure_no in (select structure_no from structure_user_info where user_id='" + creatorId + "' and user_type='USER')) " + //同级好友列表
                "and parent_no=structure_no and structure_type=1 and del_flag=0";
        List<StructureInfoVO> vos = getStructureInfoVOS(sql);
        if (vos.isEmpty()) {
            return gson.toJson(RetResult.successResult("查询成功", new ArrayList()));
        }
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("select structure_no,structure_name,structure_level,creator_id,creator_name,parent_no,is_finish,create_time,finish_time,structure_type,case_type,structure_desc,gb28181_export" +
                " from structure_info where");

        if (vos.size() == 1) {
            stringBuilder.append(" structure_no='" + vos.get(0).getStructureNo() + "'");
        } else {
            stringBuilder.append(" structure_no in (");
            for (int i = 0; i < vos.size(); i++) {
                if (i == vos.size() - 1) {
                    stringBuilder.append("'" + vos.get(i).getStructureNo() + "')");
                } else {
                    stringBuilder.append("'" + vos.get(i).getStructureNo() + "',");
                }
            }
        }
        List<StructureInfoVO> structureInfoVOS = getStructureInfoVOS(stringBuilder.toString());
        List<StructureInfoVO> list = new ArrayList<>();
        for (StructureInfoVO vo : vos) {
            StructureInfoVO sv = obtainStructuresTree(structureInfoVOS, vo);
            list.add(sv);
        }

        return gson.toJson(RetResult.successResult("查询成功!", list));
    }

    private StructureInfoVO obtainStructuresTree(List<StructureInfoVO> vos, StructureInfoVO vo) {
        List<StructureInfoVO> list = new ArrayList<>();
        for (StructureInfoVO v : vos) {
            if (v.getParentNo().equals(vo.getStructureNo())
                    && !v.getParentNo().equals(v.getStructureNo())) {
                list.add(v);
            }
        }
        if (!list.isEmpty()) {
            vo.setChildList(list);
            for (StructureInfoVO infoVO : vo.getChildList()) {
                obtainStructuresTree(vos, infoVO);
            }
        }
        return vo;
    }


    private String deleteStructuresByNo(String structureNo) throws Exception {
        List<StructureInfoVO> vos = queryByLikeNo(structureNo);
        if (vos.isEmpty()) {
            return gson.toJson(RetResult.failResult("案件不存在!"));
        }
        List<String> list = new ArrayList<>();
        Vector<Vector<?>> vector = LogicProcessor2.db.queryData("select structure_no from structure_info where parent_no='" + structureNo + "'");
        if (vector.size() <= 1) {
            list.add("delete from structure_info where structure_no='" + structureNo + "'");
            list.add("delete from structure_user_info where structure_no='" + structureNo + "'");
        } else {
            StringBuilder sql = new StringBuilder("update structure_info set del_flag=1 where structure_no in ('");
            StringBuilder sql1 = new StringBuilder("update structure_user_info set del_flag=1 where structure_no in ('");
            for (int i = 0; i < vos.size(); i++) {
                StructureInfoVO vo = vos.get(i);
                if (i == vos.size() - 1) {
                    sql.append(vo.getStructureNo()).append("');");
                    sql1.append(vo.getStructureNo()).append("');");
                } else {
                    sql.append(vo.getStructureNo()).append("','");
                    sql1.append(vo.getStructureNo()).append("','");
                }
            }
            list.add(sql.toString());
            list.add(sql1.toString());
        }
        Boolean update = LogicProcessor2.db.update(list, true);
        return update ? gson.toJson(RetResult.successResult("删除成功!")) : gson.toJson(RetResult.failResult("删除失败!系统异常!"));
    }

    private List<StructureInfoVO> queryByLikeNo(String structureNo) throws Exception {
        String querySql = "select structure_no,structure_name,structure_level," +
                "creator_id,creator_name,parent_no,is_finish,create_time,finish_time,structure_type,case_type,structure_desc,gb28181_export from structure_info " +
                "where structure_type=1 and structure_level like '%" + structureNo + "%'";

        return getStructureInfoVOS(querySql);
    }

    private List<StructureInfoVO> getStructureInfoVOS(String querySql) throws Exception {
        Vector<Vector<?>> vectors = LogicProcessor2.db.queryData(querySql);
        List<StructureInfoVO> vos = new ArrayList<>();
        if (vectors.isEmpty()) {
            return vos;
        }

        for (Vector<?> v : vectors) {
            int i = 0;
            StructureInfoVO vo = new StructureInfoVO();
            vo.setStructureNo(v.get(i).toString());
            vo.setStructureName(v.get(++i).toString());
            vo.setStructureLevel(v.get(++i).toString());
            vo.setCreatorId(v.get(++i).toString());
            vo.setCreatorName(v.get(++i).toString());
            vo.setParentNo(v.get(++i).toString());
            vo.setIsFinish(Integer.valueOf(v.get(++i).toString()));
            vo.setCreateTime(v.get(++i).toString());
            vo.setFinishTime(v.get(++i).toString());
            vo.setStructureType(Integer.valueOf(v.get(++i).toString()));
            vo.setCaseType(v.get(++i).toString());
            vo.setStructureDesc(v.get(++i).toString());
            vo.setGb28181Export(Integer.valueOf(v.get(++i).toString()));
            vos.add(vo);
        }
        return vos;
    }

    private String updateStructuresByNo(String structureNo, String structureName, String structureDesc, Integer gb28181Export) throws Exception {
        List<StructureInfoVO> vos = queryByLikeNo(structureNo);
        if (vos.isEmpty()) {
            return gson.toJson(RetResult.failResult("案件不存在!"));
        }


        List<String> list2 = new ArrayList<>();
        if (EmptyUtils.isNotEmpty(structureName)) {
            list2.add("structure_name = '" + structureName + "'");
        }
        if (EmptyUtils.isNotEmpty(gb28181Export)) {
            list2.add("gb28181_export = " + gb28181Export );
        }
        if (EmptyUtils.isNotEmpty(structureDesc)) {
            list2.add("structure_desc = '" + structureDesc + "'");
        }
        String sql = "update structure_info set " + EmptyUtils.getStringSplitValue(list2) + " where structure_no = '" + structureNo + "' and structure_type=1";
        List<String> list = new ArrayList<>();
        list.add(sql);
        boolean update = LogicProcessor2.db.update(list, true);

        return update ? gson.toJson(RetResult.successResult("修改成功!")) :
                gson.toJson(RetResult.failResult("修改失败!系统异常!"));
    }


    private String addStructures(List<StructureInfoVO> vos) throws Exception {
        List<String> list = new ArrayList<>();
        for (StructureInfoVO vo : vos) {
            if (EmptyUtils.isNotEmpty(vo.getCaseType())) { //节点
                String sql = "insert into structure_info (structure_no,structure_name," +
                        "structure_level,creator_id,creator_name,parent_no,structure_type,case_type,root_no) values ('" + vo.getStructureNo() + "','" +
                        vo.getStructureName() + "','" + vo.getStructureLevel() + "','" + vo.getCreatorId() + "','" +
                        vo.getCreatorName() + "','" + vo.getParentNo() + "','" + vo.getStructureType() + "','" + vo.getCaseType() + "','" + vo.getRootNo() + "');";
                list.add(sql);
            } else {
                String sql = "insert into structure_info (structure_no,structure_name," +
                        "structure_level,creator_id,creator_name,parent_no,structure_type,structure_desc,root_no) values ('" + vo.getStructureNo() + "','" +
                        vo.getStructureName() + "','" + vo.getStructureLevel() + "','" + vo.getCreatorId() + "','" +
                        vo.getCreatorName() + "','" + vo.getParentNo() + "','" + vo.getStructureType() + "','" + vo.getStructureDesc() + "','" + vo.getRootNo() + "');";
                list.add(sql);
            }
            String sql1 = "insert into structure_user_info(structure_no,user_id,user_type) values ('" + vo.getStructureNo() + "','" +
                    vo.getCreatorId() + "','" + CaseUserType.OBSERVER.name() + "');";
            list.add(sql1);
        }

        Boolean update = LogicProcessor2.db.update(list, true);

        return update ? gson.toJson(RetResult.successResult("添加成功!")) : gson.toJson(RetResult.failResult("添加失败!系统异常!"));
    }


    /**
     * 判断同一组织下  组织名称是否存在
     *
     */
    private Boolean exitStructureName(String parentNo, String structureName) throws Exception {
        String sql = "select * from structure_info where parent_no='" + parentNo + "' and structure_name='" + structureName + "'";
        Vector<Vector<?>> vector = LogicProcessor2.db.queryData(sql);
        return !vector.isEmpty();
    }

    /**
     * 判断AJ是否完结
     *
     */
    private Boolean finishStructure(String structureNo) throws Exception {
        String sql = "select is_finish from structure_info where structure_no='" + structureNo + "' and is_finish=1";
        Vector<Vector<?>> vector = LogicProcessor2.db.queryData(sql);
        return !vector.isEmpty();
    }

    /**
     * 判断是否为管理员用户
     *
     */
    private Boolean isAdmin(String userId) throws Exception {
        String sql = "select account_type from g_users where del_flag = 0 and user_uid='" + userId + "'";
        Vector<Vector<?>> vector = LogicProcessor2.db.queryData(sql);
        int integer = Integer.parseInt((String) vector.get(0).get(0));
        return integer != 1;
    }

    /**
     * 通过组织编码获取层级编码
     *
     */
    private Vector<Vector<?>> queryLevelByNo(String structureNo) throws Exception {
        String sql = "select root_no,structure_level from structure_info where structure_no='" + structureNo + "'";
        return LogicProcessor2.db.queryData(sql);
    }


    /**
     * 是否为AJ观察员
     *
     */
    private Boolean isObserver(String structureNo, String userId) throws Exception {
        String sql = "select * from structure_user_info where structure_no=(select root_no from structure_info where structure_no='" + structureNo + "')  and user_id='" + userId + "'";
        Vector<Vector<?>> vector = LogicProcessor2.db.queryData(sql);
        return !vector.isEmpty();
    }

    /**
     * 是否为AJ创建者
     *
     */
    private Boolean isCreator(String structureNo, String userId) throws Exception {
        String sql = "select * from structure_info where structure_no='" + structureNo + "' and creator_id='" + userId + "'";
        Vector<Vector<?>> vector = LogicProcessor2.db.queryData(sql);
        return !vector.isEmpty();
    }


    /**
     * AJ 完结
     *
     */
    private String finishStructureByNo(String structureNo) throws Exception {
        List<String> list = new ArrayList<>();
        //AJ和下面子节点设置为已完结
        String sql = "update structure_info set is_finish=1,finish_time=" + DBDepend.getDefaultDatetimeFunc() + " where structure_level like '%" + structureNo + "%'";
        list.add(sql);
        //观察者和设备设置为已完结
        list.add("update structure_user_info set is_finish=1 where structure_no='" + structureNo + "'");
        boolean update = LogicProcessor2.db.update(list, true);
        return update ? gson.toJson(RetResult.successResult("操作成功!")) :
                gson.toJson(RetResult.failResult("操作失败!"));
    }


    /**
     * 是否包含导出功能
     *
     */
    public Boolean exoprtAuth(String structureNo) throws Exception {
        String sql = "select gb28181_export from structure_info where structure_no='" + structureNo + "' and gb28181_export=1";
        Vector<Vector<?>> vector = LogicProcessor2.db.queryData(sql);
        return !vector.isEmpty();
    }

    /**
     * 通知导出gb28181
     *
     * @param structureNo、
     */
    public void notifyGb28181Export(String structureNo) throws Exception {
        String sql = "select d.user_uid,d.user_mail,g.gb28181_id from " +
                "g_users d left join my_gb28181 g on d.user_uid=g.dev_id " +
                "where d.del_flag = 0 and d.user_uid in (select user_id from structure_user_info " +
                "where user_type='DEVICE' and is_finish=0 and structure_no in (select structure_no " +
                "from structure_info where root_no='" + structureNo + "'))";
      //  Vector<Vector> vector = LogicProcessor2.db.queryData(sql);
       // RedisManager.getJedis().publish(RedisConfig.PUSH_SERVICE,vector.toString());

    }

}
